package cn.rayland.rayland3d.activity;

import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import cn.rayland.library.bean.FileTask;
import cn.rayland.library.bean.MachineState;
import cn.rayland.library.bean.MachineTask;
import cn.rayland.library.bean.SliceSetting;
import cn.rayland.library.utils.ConvertUtils;
import cn.rayland.rayland3d.R;
import cn.rayland.rayland3d.app.App;
import utils.EasySharePreference;
import utils.FileServer;
import utils.SliceParamter;
import utils.WebSocketPusher;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    private static final String TAG = MainActivity.class.getSimpleName();
    private Button printStl;
    private Button printStlLocal;
    private Button printGcode;
    private Button printX3g;
    private Button controlPrint;
    private Button cancelPrint;
    private Button pushWebSocket;
    private Button customPrint;
    private FileTask task = new FileTask();
    private final static String stlPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/test.stl";
    private final static String gcodePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/test.gcode";
    private final static String x3gPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/test.x3g";
    private ProgressDialog dialog;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        copyTestFile();
        initView();
        //文件转换回调
        task.setConvertCallback(new MachineTask.ConvertCallback() {
            @Override
            public void onPreConvert(String type) {
                //开始转换前执行
                showProgressDialog(MainActivity.this, "start convert");
            }

            @Override
            public void onConvertProgress(String type, int progress) {
                //转换进度
                switch (type) {
                    case ConvertUtils.UPLOAD_STL:
                        dialog.setIndeterminate(false);
                        dialog.setMessage("uploading stl file");
                        if (progress == 100) {
                            dialog.setIndeterminate(true);
                            dialog.setMessage("slicing stl file");
                        }
                        break;
                    case ConvertUtils.DOWNLOAD_STL:
                        dialog.setIndeterminate(false);
                        dialog.setMessage("downloading gcode file");
                        break;
                    case ConvertUtils.GCODE_TO_X3G:
                        dialog.setIndeterminate(false);
                        dialog.setMessage("converting gcode to x3g");
                        break;
                    default:
                        dialog.setIndeterminate(true);
                        dialog.setMessage("current step: "+type);
                        break;
                }
                dialog.setProgress(progress);
            }

            @Override
            public void onConvertSuccess(String type) {
                //转换成功执行
                if (type == ConvertUtils.GCODE_TO_X3G) {
                    dialog.dismiss();
                    Toast.makeText(getApplicationContext(), "预计用时：" + task.getNeedTime() + " S", Toast.LENGTH_SHORT).show();
                }
            }

            @Override
            public void onConvertFailed(String type, String error) {
                //转换失败执行
                dialog.dismiss();
                Toast.makeText(MainActivity.this, type == ConvertUtils.STL_TO_GCODE ? "slice stl failed"
                        : (type.equals(ConvertUtils.DOWNLOAD_STL) ? "download stl failed"
                        : (type.equals(ConvertUtils.GCODE_TO_X3G) ? "convert gcode to x3g failed"
                        : (type.equals(ConvertUtils.UPLOAD_STL) ? "upload stl failed"
                        : type+" failed"))), Toast.LENGTH_LONG).show();
            }
        });
        //设置Gcode(M900,M114)回调
        task.setGcodeCallback(gcodeCallback);
        //设置Task(onStart,onFinished...)回调
        task.setTaskCallback(taskCallback);
        //设置切片参数
        SliceSetting setting = new SliceSetting();
        setting.setEngine(SliceParamter.DEFAULT_ENGINE);
        setting.setLayerThickness(SliceParamter.DEFAULT_SLICEHEIGHT);
        setting.setRetrac_length(SliceParamter.DEFAULT_RETRAC_LENGTH);
        setting.setSpeed(SliceParamter.DEFAULT_SPEED);
        setting.setSupport(SliceParamter.DEFAULT_CURA_SUPPORT);
        setting.setTemp(SliceParamter.DEFAULT_TEMPER);
        setting.setOffset_x(0f);
        setting.setOffset_y(0f);
        setting.setOffset_z(0f);
        setting.setScale(1f);
        setting.setRotate_z(0f);
        setting.setAdhesion("raft");
        task.setSliceSetting(setting);
    }

    //拷贝测试用的stL\gcode\x3g文件
    private void copyTestFile() {
        new Thread(){
            @Override
            public void run() {
                super.run();
                if(!new File(stlPath).exists()){
                    copyFromAssets(stlPath.substring(stlPath.lastIndexOf("/")+1), stlPath);
                }
                if(!new File(gcodePath).exists()){
                    copyFromAssets(gcodePath.substring(gcodePath.lastIndexOf("/")+1), gcodePath);
                }
                if(!new File(x3gPath).exists()){
                    copyFromAssets(x3gPath.substring(x3gPath.lastIndexOf("/")+1), x3gPath);
                }
            }
        }.start();
    }

    private void copyFromAssets(String assetsFilePath, String destiFilePath){
        InputStream is = null;
        FileOutputStream fos = null;
        try {
            is = getAssets().open(assetsFilePath);
            File file = new File(destiFilePath);
            if(!file.exists()){
                file.createNewFile();
            }
            fos = new FileOutputStream(file);
            byte[] bytes = new byte[1024];
            int length;
            while((length = is.read(bytes))!=-1){
                fos.write(bytes, 0, length);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(is != null){
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(fos != null){
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    //初始化各组件
    private void initView() {
        printStl = (Button) findViewById(R.id.stlPrintCloud);
        printStl.setOnClickListener(this);
        printStlLocal = (Button) findViewById(R.id.stlPrintLocal);
        printStlLocal.setOnClickListener(this);
        printGcode = (Button) findViewById(R.id.gcodePrint);
        printGcode.setOnClickListener(this);
        printX3g = (Button) findViewById(R.id.x3gPrint);
        printX3g.setOnClickListener(this);
        controlPrint = (Button) findViewById(R.id.printControl);
        controlPrint.setOnClickListener(this);
        cancelPrint = (Button) findViewById(R.id.stop_print);
        cancelPrint.setOnClickListener(this);
        pushWebSocket = (Button) findViewById(R.id.push_websocket);
        pushWebSocket.setOnClickListener(this);
        customPrint = (Button) findViewById(R.id.customPrint);
        customPrint.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.stlPrintCloud:
                task.setContent(new File(stlPath));
                task.setTaskName(stlPath);
                task.getSliceSetting().setEngine(SliceParamter.DEFAULT_ENGINE);
                App.machineManager.sendTask(task, true);
                break;
            case R.id.stlPrintLocal:
                task.setContent(new File(stlPath));
                task.setTaskName(stlPath);
                task.getSliceSetting().setEngine(SliceParamter.LOCAL_ENGINE);
                App.machineManager.sendTask(task, true);
                break;
            case R.id.gcodePrint:
                task.setContent(new File(gcodePath));
                task.setTaskName(gcodePath);
                App.machineManager.sendTask(task, true);
                break;
            case R.id.x3gPrint:
                task.setContent(new File(x3gPath));
                task.setTaskName(x3gPath);
                App.machineManager.sendTask(task, true);
                break;
            case R.id.printControl:
                startActivity(new Intent(MainActivity.this, ControlActivity.class));
                break;

            case R.id.stop_print:
                App.machineManager.cancel(true);
                break;

            case R.id.push_websocket:
                startActivity(new Intent(MainActivity.this, PushWebSocketActivity.class));
                break;

            case R.id.customPrint:
                Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
                intent.setType("*/*");
                intent.addCategory(Intent.CATEGORY_OPENABLE);
                startActivityForResult(Intent.createChooser(intent, "Select a file"), 0);
                break;
        }
    }

    /**
     * 显示进度条提示
     * @param context
     * @param message
     */
	private void showProgressDialog(final Context context, String message) {
        if(dialog == null){
            dialog = new ProgressDialog(context);
        }
        dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
		dialog.setIndeterminate(false);
		dialog.setMessage(message);
		dialog.setCanceledOnTouchOutside(false);
        dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
            @Override
            public void onDismiss(DialogInterface dialog) {
                //停止文件转换
                ConvertUtils.cancelConvert();
            }
        });
		dialog.show();
	}

    private MachineTask.TaskCallback taskCallback = new MachineTask.TaskCallback() {
        @Override
        public void onStart() {
            //开始执行前调用此方法
            Log.d(TAG, "onStart");
            startActivity(new Intent(MainActivity.this, StateActivity.class));
            if (EasySharePreference.getPrefInstance(getApplicationContext()).getBoolean("ifpush", false)){
                WebSocketPusher.startPush(EasySharePreference.getPrefInstance(getApplicationContext()).getString("pushAddress", "") + ":" + EasySharePreference.getPrefInstance(getApplicationContext()).getInt("pushPort", 8001),
                        EasySharePreference.getPrefInstance(getApplicationContext()).getInt("pushTime", 10000),  App.machineManager);
                FileServer.open(EasySharePreference.getPrefInstance(getApplicationContext()).getInt("trasPort", 8002));
            }
        }

        @Override
        public void onError() {
            //执行遇到错误调用此方法
            Log.d(TAG, "onError");
            WebSocketPusher.stopPush();
        }

        @Override
        public void onCancel() {
            //取消执行时调用此方法
            Log.d(TAG, "onCancel");
            WebSocketPusher.stopPush();
        }

        @Override
        public void onFinished() {
            //执行结束后调用此方法
            Log.d(TAG, "onFinished");
            WebSocketPusher.stopPush();
        }
    };

    private MachineTask.GcodeCallback gcodeCallback = new MachineTask.GcodeCallback() {
        @Override
        public void onM900(float distance) {
            //M900回调
            Log.d(TAG, "height = " + distance + "");
        }

        @Override
        public void onM114(float[] positions) {
            //M114回调
//            Log.d(TAG, "坐标 = " + positions[0] + "/" + positions[1] + "/" + positions[2]);
        }
    };

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if(requestCode == 0){
            if(resultCode == RESULT_OK){
                Uri uri = data.getData();
                task.setContent(new File(uri.getPath()));
                task.setTaskName(uri.getPath());
                task.getSliceSetting().setEngine(SliceParamter.LOCAL_ENGINE);
                App.machineManager.sendTask(task, true);
            }
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        FileServer.close();
    }
}
